package top.haijunit.mark.common.core;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.*;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.Map;
import java.util.Objects;

/**
 * @Author 爱做梦的奋斗青年
 * @Date 2021/10/12 0012 17:47
 * @description
 */
@Slf4j
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Result<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    /** 成功标记 */
    private static final Integer SUCCESS = 0;
    /** 失败标记 */
    private static final Integer FAIL = 1;


    @Getter
    @Setter
    private int code;

    @Getter
    @Setter
    private String msg;

    @Getter
    @Setter
    private T data;

    public static <T> Result<T> ok() {
        return restResult(null, SUCCESS, null);
    }

    public static <T> Result<T> ok(String msg) {
        return restResult(null, SUCCESS, msg);
    }

    public static <T> Result<T> ok(T data, String msg) {
        return restResult(data, SUCCESS, msg);
    }

    public static <T> Result<T> failed() {
        return restResult(null, FAIL, null);
    }

    public static <T> Result<T> failed(String msg) {
        return restResult(null, FAIL, msg);
    }

    public static <T> Result<T> failed(T data, String msg) {
        return restResult(data, FAIL, msg);
    }

    private static <T> Result<T> restResult(T data, int code, String msg) {
        Result<T> apiResult = new Result<>();
        apiResult.setCode(code);
        apiResult.setData(data);
        apiResult.setMsg(msg);
        return apiResult;
    }

    public Result addData(String key, Object value) {
        if (Objects.isNull(this.data)) {
            this.data = (T) JSONUtil.createObj().set(key, value);
        } else if (this.data instanceof Map) {
            Map map = (Map) this.data;
            map.put(key, value);
        } else if (this.data instanceof JSONObject) {
            JSONObject jsonObject = (JSONObject) this.data;
            jsonObject.set(key, value);
        } else {
            log.error("Result type not addData, type name is {}",this.data.getClass().getTypeName());
        }
        return this;
    }

}
